#include <8052.h>
#include "I2C.h"
#include "eeprom.h"


//EEPROM按地址写入
void eeprom_write_address(unsigned char address, unsigned char data)
{
    I2C_Start();
    I2C_Send_Byte(0xa0);
    I2C_Wait_ACK();
    I2C_Send_Byte(address);
    I2C_Wait_ACK();
    I2C_Send_Byte(data);
    I2C_Wait_ACK();
    I2C_Stop();
}

//EEPROM按地址读取
unsigned char eeprom_read_address(unsigned char address)
{
    unsigned char data;
    I2C_Start();
    //写设备地址为 1010xxx0
    I2C_Send_Byte(0xa0);
    I2C_Wait_ACK();
    //写入要访问的地址
    I2C_Send_Byte(address);
    I2C_Wait_ACK();
    //重新开始
    I2C_Start();
    //读设备地址为 1010xxx1
    I2C_Send_Byte(0xa1);
    I2C_Wait_ACK();
    data = I2C_Read_Byte();
    I2C_Stop();
    return data;
}

//EEPROM按地址写入
//通过传递数组名参数到子函数中，以获得数组长度是不可行的,所以要增加字段长度
//https://blog.csdn.net/qq_39516859/article/details/82464346
void eeprom_write_string(unsigned char address, unsigned char data[], unsigned char size)
{
    I2C_Start();
    I2C_Send_Byte(0xa0);
    I2C_Wait_ACK();
    I2C_Send_Byte(address);
    I2C_Wait_ACK();
    for (unsigned int i = 0; i < size; i++)
    {
        I2C_Send_Byte(data[i]);
        I2C_Wait_ACK();
    }
    I2C_Stop();
}

//EEPROM按地址读取
//Figure 6. Sequential Read
//返回数组指针
//该方法不可直接使用，待完善,主要是不能自动分配内存
char *eeprom_read_string(unsigned char address, unsigned char size)
{
    //内存分配，比如字符串内存动态分配
    //由于80c52的内存太小，不能直接使用malloc直接分配内存，使用固定数据方式分配
    // char *p;
    // p = (char *)malloc(100);
    //calloc(size,1);
    unsigned char data[8]; //AT24C02最大小256x8bit=2K的大小,PlatformIO最大只能定义一定长度大小，如果程序中所有变量大于xx，就编译不过

    I2C_Start();
    //写设备地址为 1010xxx0
    I2C_Send_Byte(0xa0);
    I2C_Wait_ACK();
    //写入要访问的地址
    I2C_Send_Byte(address);
    I2C_Wait_ACK();
    //重新开始
    I2C_Start();
    //读设备地址为 1010xxx1
    I2C_Send_Byte(0xa1);
    I2C_Wait_ACK();
    for (char i = 0; i < size; i++)
    {
        data[i] = I2C_Read_Byte();
        //https://codeantenna.com/a/usIy24vZPs
        //IIC协议规定，当主机作为接收设备时，主机对最后一个字节不应答，以向发送设备(从设备)标识数据传送结束。
        if (i != size - 1)
        {
            I2C_Send_ACK();
        }
    }
    I2C_Stop();

    return data;
}

//延时
void Delay601ms() //@11.0592MHz
{
    unsigned char i, j, k;

    i = 5;
    j = 27;
    k = 142;
    do
    {
        do
        {
            while (--k)
                ;
        } while (--j);
    } while (--i);
}


void i2c_eeprom()
{
    //I2C_Init();
    char address = 0;
    //按地址写字节
    eeprom_write_address(address, 0xaa);    
    I2C_Delay_10ms();//写入读之间的时间范围文档定义最大可能是10ms
    //按地址读字节
    P1 = eeprom_read_address(address);

    Delay601ms();

    //用于流水灯展示的数据
    unsigned char keys[] = {0b11111110, 0b11111101, 0b11111011, 0b11110111, 0b11101111, 0b11011111, 0b10111111, 0b01111111};
    //unsigned char keys[] = {0b01111111, 0b10111111, 0b11011111, 0b11101111, 0b11110111, 0b11111011, 0b11111101, 0b11111110};
    // sizeof(keys) / sizeof(keys[0]) 用于取数组内个数
    unsigned char size = sizeof(keys) / sizeof(keys[0]);

    //写
    eeprom_write_string(address, keys, size);
    I2C_Delay_10ms();

    //读
    char *data = eeprom_read_string(address, size);
    for (char i = 0; i < size; i++)
    {
        P1 = data[i];
        Delay601ms();
    }
    //按地址读取
    // for (char i = 0; i < size; i++)
    // {
    //     P1 = eeprom_read_address(i);
    //     Delay601ms();
    // }
}
